import json, re, logging
from django.http import JsonResponse
from django.views import View
from django.contrib.auth import login, authenticate, logout
from django.conf import settings
from django_redis import get_redis_connection
from PIL import Image
from io import BytesIO
from fdfs_client.client import Fdfs_client
from users.models import User
from myhome.utils.loginrequired import LoginRequired

logger = logging.getLogger('django')


class RegisterView(View):

    def post(self, request):

        '''
        用户注册页面
        '''
        # 1.提取参数
        data = json.loads(request.body.decode())
        mobile = data.get('mobile')
        phonecode = data.get('phonecode')
        password = data.get('password')
        # 2. 检验参数
        if not all([mobile, phonecode, password]):
            return JsonResponse({
                'erron': '4103',
                'errmsg': '参数有误'
            })
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({
                'errno': '4004',
                'errmsg': '手机号格式错误'
            })

        if not re.match(r'^[0-9a-zA-Z]{8,20}$', password):
            return JsonResponse({
                'errno': '4004',
                'errmsg': '密码格式错误'
            })

        # 短信验证码校验
        try:
            conn = get_redis_connection('verify_code')
            sms_code = conn.get('sms_%s' % mobile)
        except Exception as e:
            logger.error(e)
            return JsonResponse({
                'errno': '4001',
                'errmsg': '查询数据库失败'
            })

        # 判断验证码是否存在
        if not sms_code:
            return JsonResponse({
                'errno': '4004',
                'errmsg': '短信验证码已经过期'
            })
            # 判断短信验证码是否一致
        if phonecode != sms_code.decode():
            return JsonResponse({
                'errno': '4004',
                'errmsg': '短信验证码输入错误'
            })
        # 3.保存数据到数据库
        try:
            user = User.objects.create_user(
                username=mobile,
                mobile=mobile,
                password=password
            )
        except Exception as e:
            logger.error(e)
            return JsonResponse({
                'errno': '4001',
                'errmsg': '数据库保存失败'

            })
        # 添加状态保持
        login(request, user)

        response = JsonResponse({'errno': '0', 'errmsg': '注册成功'})
        response.set_cookie('username', user.username)

        # 3. 构建响应返回
        return response


class LoginView(View):

    def post(self, request):

        '''
        用户登录
        '''

        # 1.提取参数
        data = json.loads(request.body.decode())
        mobile = data.get('mobile')
        password = data.get('password')
        # 2.校验参数
        if not all([mobile, password]):
            return JsonResponse({
                'errno': '4103',
                'errmsg': '参数不全'
            })
        if not re.match('^[0-9a-zA-Z]{8,20}$', password):
            return JsonResponse({
                'errno': 4004,
                'errmsg': '密码格式错误'
            })
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({
                'errno': '4004',
                'errmsg': '手机号格式错误'
            })
        # 验证是否能够登录
        User.USERNAME_FIELD = 'mobile'
        user = authenticate(username=mobile, password=password)

        if not user:
            return JsonResponse({
                'errno': '4104',
                'errmsg': '用户名或者密码错误'
            })
        login(request, user)

        response = JsonResponse({'errno': '0', 'errmsg': '登录成功'})
        response.set_cookie('username', user.username)
        return response

    def get(self, request):

        '''
        判断用户是否登录
        '''

        user = request.user
        if not user.is_authenticated:
            return JsonResponse({
                'errno': 4101,
                'errmsg': '未登录'
            })

        return JsonResponse({
            'errno': '0',
            'errmsg': '已登录',
            'data': {
                'name': user.username,
                'user_id': user.id
            }
        })

    def delete(self, request):

        '''
        退出登录
        '''

        logout(request)
        response = JsonResponse({
            "errno": "0",
            "errmsg": "已登出"
        })

        return response


class Usercenter(LoginRequired, View):

    def get(self, request):

        user_id = request.user.id
        user = request.user
        avatar = user.avatar

        # 判断是否已经上传过图片
        if not avatar:
            url = ''
        else:
            url = settings.FDFS_URL + avatar

        data = {
            'avatar_url': url,
            'create_time': user.date_joined,
            'mobile': user.mobile,
            'name': user.username,
            'user_id': user_id
        }

        return JsonResponse({
            'errmsg': 'ok',
            'errno': '0',
            'data': data
        })


class UserChangehead(LoginRequired, View):

    def post(self, request):

        user_id = request.user.id
        user_image = request.FILES.get('avatar')

        if user_image is None:
            return JsonResponse({
                'errno': '4002',
                'errmsg': '未上传头像'

            })
        # 图片大小处理
        user_image = user_image.file.getvalue()
        image = Image.open(BytesIO(user_image))
        house_IMG = image.resize((364, 312), Image.ANTIALIAS)
        img = BytesIO()
        house_IMG.save(img, format='JPEG')
        img = img.getvalue()

        client = Fdfs_client('myhome/utils/fastdfs/client.conf')
        ret = client.upload_by_buffer(img)
        url_end = ret.get('Remote file_id')
        # url_end = '/'.join(url_end.split('\\'))

        try:
            User.objects.filter(id=user_id).update(avatar=url_end)
        except Exception as e:
            logger.error(e)
            return JsonResponse({
                'errno': '4302',
                'errmsg': '保存头像失败'
            })

        url = settings.FDFS_URL + url_end

        return JsonResponse({
            'data': {'avatar_url': url},
            'errno': '0',
            'errmsg': '头像上传成功'
        })


class UserChangeName(LoginRequired, View):

    def put(self, request):

        dict = json.loads(request.body.decode())
        name = dict.get('name')
        user_id = request.user.id
        try:
            User.objects.filter(id=user_id).update(username=name)

        except Exception as e:
            return JsonResponse({
                'errno': '4302',
                'errmsg': '修改失败'

            })
        return JsonResponse({
            'errno': '0',
            'errmsg': '修改成功'
        })


class UserRealName(LoginRequired, View):

    def post(self, request):

        dict = json.loads(request.body.decode())
        real_name = dict.get('real_name')
        id_card = dict.get('id_card')

        # 检验参数
        if not all([real_name, id_card]):
            return JsonResponse({'erron': '4103', 'errmsg': '缺少参数'})

        # 匹配姓名，可匹配中文或英文姓名
        if not re.match(r'^(([a-zA-Z+\.?\·?a-zA-Z+]{2,30}$)|([\u4e00-\u9fa5+\·?\u4e00-\u9fa5+]{2,30}$))$', real_name):
            return JsonResponse({'errno': '4103', 'errmsg': '名字格式错误'})

        # 省份证匹配
        if not re.match(r'^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$',
                        id_card):
            return JsonResponse({'errno': '4103', 'errmsg': '身份证格式错误'})

        try:
            request.user.real_name = real_name
            request.user.id_card = id_card
            request.user.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': '4302', 'errmsg': '保存失败'})

        dict = {'real_name': real_name, 'id_card': id_card}
        return JsonResponse({"errno": "0",
                             "errmsg": "认证信息保存成功",
                             'data': dict})

    def get(self, request):
        user = request.user
        real_name = user.real_name
        id_card = user.id_card
        dict = {'real_name': real_name, 'id_card': id_card}
        return JsonResponse({"errno": "0",
                             "errmsg": "认证信息保存成功",
                             'data': dict})
